/**
 * Smart dialog - jQuery EasyUI Extension
 * 
 * Copyright (c) 2009-2013 Rime Lee. All rights reserved.
 */
(function($) {
	$.fn.joyform = function(options, param) {
		if (typeof options == 'string') {
			var method = $.fn.joyform.methods[options];
			if (method) {
				return method(this, param);
			} else {
				return this.dialog(options, param);
			}
		}

		options = options || {};
		return this.each(function() {
			var state = $.data(this, 'joyform');
			if (state) {
				$.extend(state.options, {
					readonly : false
				}, options);
				initDialog(this);
			} else {
				state = {
					options : $.extend({}, $.fn.joyform.defaults, options, {
						loadData : function(data) {
							buildForm(this, data);
						}
					})
				};
				$.data(this, 'joyform', state);
				createForm(this);
			}
		});
	};

	function createForm(target) {
		var opts = $.data(target, 'joyform').options;
		var panel = $("<div></div>").appendTo(target).css({
			"border" : "0",
			"margin" : "0",
			"padding" : "0",
			"width" : opts.width - 20
		}).addClass("joyform-panel");
		$("<table></table>").appendTo(panel).addClass("joyform-content");
		if (opts.dialog) {
			initDialog(target);
		} else {
			initForm(target);
		}
	}

	function initDialog(target) {
		var opts = $.data(target, 'joyform').options;
		var buttons = null;
		if (opts.readonly) {
			buttons = [ {
				text : "关闭",
				iconCls : 'icon-cancel',
				handler : function() {
					$(target).dialog('close');
				}
			} ];
		} else {
			buttons = [ {
				text : opts.submit.name,
				iconCls : opts.submit.iconCls,
				handler : function() {
					$(this).linkbutton('disable');
					$(this).linkbutton({
						text : '处理中',
						iconCls : 'icon-loading'
					});
					if (!submit(target)) {
						$(this).linkbutton({
							text : opts.submit.name,
							iconCls : opts.submit.iconCls
						});
						$(this).linkbutton('enable');
					}
				}
			}, {
				text : "关闭",
				iconCls : 'icon-cancel',
				handler : function() {
					$(target).dialog('close');
				}
			} ];
		}
		$(target).dialog({
			title : opts.title,
			width : opts.width,
			height : opts.height,
			closed : true,
			cache : false,
			modal : true,
			buttons : buttons,
			onOpen : function() {
				if (opts.data) {
					buildForm(target, opts.data);
				} else {
					$.jsonloader(target, opts);
				}
			}
		});
	}

	function initForm(target) {
		var opts = $.data(target, 'joyform').options;
		var content = getContent(target);
		var btnbar = $('<div></div>').insertAfter(content).addClass("joyform-button-bar");
		btnbar.hide();
		var button = $('<a href="#"></a>').linkbutton({
			text : opts.submit.name,
			iconCls : opts.submit.iconCls,
		}).appendTo(btnbar).addClass('joyform-button');
		button.bind('click', function() {
			$(this).linkbutton('disable');
			$(this).linkbutton({
				text : '处理中',
				iconCls : 'icon-loading'
			});
			if (!submit(target)) {
				$(this).linkbutton({
					text : opts.submit.name,
					iconCls : opts.submit.iconCls
				});
				$(this).linkbutton('enable');
			}
		});
		if (opts.data) {
			buildForm(target, opts.data);
		} else {
			$.jsonloader(target, opts);
		}
	}

	function getContent(target) {
		return $(target).find('table.joyform-content');
	}

	function getButtons(target) {
		var opts = $.data(target, 'joyform').options;
		if (opts.dialog && (opts.dialog == true)) {
			return $(target).find('div.dialog-button>a');
		} else {
			return $(target).find('div.joyform-button-bar>a');
		}
	}

	function buildForm(target, data) {
		$.data(target, 'joyform').data = data;
		var opts = $.data(target, "joyform").options;
		var content = getContent(target);
		content.empty();
		if (opts.readonly) {
			content.addClass("joyform-readonly");
		} else {
			content.removeClass("joyform-readonly");
		}
		var tr = $("<tr style='height:1px;line-height:1px;'></tr>").appendTo(content);
		var lablen = getMaxLabelLength(data.rows) * 20;
		$("<th>&nbsp;</th>").appendTo(tr).css("width", lablen);
		$("<th>&nbsp;</th>").appendTo(tr);
		for (var i = 0; i < data.rows.length; i++) {
			appendRow(target, content, data.rows[i]);
		}

		if (opts.dialog && (opts.dialog == true)) {
			getButtons(target).linkbutton('enable');
		} else {
			if (opts.readonly) {
				$(target).find('div.joyform-button-bar').hide();
			} else {
				$(target).find('div.joyform-button-bar').show();
				var btn = getButtons(target);
				btn.linkbutton({
					text : opts.submit.name,
					iconCls : opts.submit.iconCls
				});
				btn.linkbutton('enable');
			}
		}
	}

	function getMaxLabelLength(fields) {
		var len = 0;
		for (var i = 0; i < fields.length; i++) {
			if (len < fields[i].label.length) {
				len = fields[i].label.length;
			}
		}
		return len;
	}

	function appendRow(target, content, field) {
		var opts = $.data(target, "joyform").options;
		var row = $("<tr></tr>").appendTo(content).addClass("joyform-row");
		$("<td></td>").appendTo(row).addClass("joyform-label").html(field.label);
		if (opts.readonly && (opts.readonly == true)) {
			appendField(target, row, field);
		} else {
			appendEditor(target, row, field);
		}
	}

	function appendField(target, row, field) {
		var td = $("<td></td>").appendTo(row).addClass("joyform-field");
		if (field.value) {
			if (field.editor) {
				td.html(formatter(field.value, field.editor));
			} else {
				td.html(field.value);
			}
		}
	}

	function formatter(value, editor) {
		if (editor.type == 'combobox') {
			var items = editor.options['data'];
			for (var i = 0; i < items.length; i++) {
				if (value == items[i].value) {
					return items[i].text;
				}
			}
			return value;
		} else if (editor.type == 'combotree') {
			var nodes = editor.options['data'];
			if (nodes && (nodes.length > 0)) {
				for (var i = 0; i < nodes.length; i++) {
					var t = getTreeText(value, nodes[i]);
					if (t) {
						return t;
					}
				}
			}
			return null;
		} else if (editor.type == 'checkbox') {
			if (value == editor.options['on']) {
				return editor.options['yes'] ? editor.options['yes'] : "是";
			} else {
				return editor.options['no'] ? editor.options['no'] : "否";
			}
		} else if (editor.type == 'password') {
			return "******";
		} else {
			return value;
		}
	}

	function getTreeText(value, node) {
		if (value == node.id) {
			return node.text;
		}
		if (node.children && (node.children.length > 0)) {
			for (var i = 0; i < node.children.length; i++) {
				var n = node.children[i];
				var t = getTreeText(value, n);
				if (t) {
					return t;
				}
			}
		}
		return null;
	}

	function appendEditor(target, row, field) {
		var td = $("<td></td>").appendTo(row).addClass("joyform-editor");
		if (field.editor) {
			if (field.editor.type == "textarea") {
				var input = $("<textarea></textarea>").attr("name", field.name).appendTo(td);
				if (field.editor.options.cols) {
					input.attr("cols", field.editor.options.cols);
				}
				if (field.editor.options.rows) {
					input.attr("rows", field.editor.options.rows);
				}
				if (field.value) {
					input.val(field.value);
				}
				if (field.editor.readonly) {
					input.prop('readonly', true);
				}
			} else if (field.editor.type == "checkbox") {
				var input = $("<input type='checkbox'></input>").attr('name', field.name).appendTo(
						td);
				if (field.value && field.value == "true") {
					input.prop('checked', true);
				}
				if (field.editor.readonly) {
					input.prop('readonly', true);
				}
			} else if ((field.editor.type == "text") || (field.editor.type == "password")
					|| (field.editor.type == "validatebox")) {
				var eltype = "text";
				if (field.editor.type == "password") {
					eltype = "password";
				}
				var input = $("<input type='" + eltype + "'></input>").attr("name", field.name)
						.appendTo(td);
				if (field.editor.options.size) {
					input.attr("size", field.editor.options.size);
				}
				if (field.value) {
					input.val(field.value);
				}
				if (field.editor.readonly) {
					input.prop('readonly', true);
				} else {
					input.validatebox(field.editor.options);
				}
			} else if ((field.editor.type == "combobox") || (field.editor.type == "combotree")
					|| (field.editor.type == "numberbox") || (field.editor.type == "datebox")
					|| (field.editor.type == "datetimebox")) {
				if (field.editor.readonly) {
					field.editor.options.readonly = true;
				}
				appendCombo(td, field);
			}
		} else {
			if (field.value) {
				td.html(field.value);
			}
		}
	}

	function appendCombo(td, field) {
		var input = $("<input name='" + field.name + "'></input>").appendTo(td);
		input[field.editor.type](field.editor.options);
		if (field.value) {
			if (field.editor.options.multiple) {
				input[field.editor.type]('setValues', field.value);
			} else {
				input[field.editor.type]('setValue', field.value);
			}
		}
	}

	function submit(target) {
		var state = $.data(target, 'joyform');
		var opts = state.options;
		var data = state.data;
		if (opts.onSubmit && (opts.onSubmit.call(target, data) == false)) {
			return false;
		}
		if (!validate(target)) {
			return false;
		}
		if (opts.submit && opts.submit.url) {
			transformDate(target, data);
			$.ajax({
				type : "POST",
				url : opts.submit.url,
				data : JSON.stringify(data),
				contentType : "application/json; charset=utf-8",
				dataType : "json",
				success : function(data) {
					var sucMsg = null;
					if (opts.onSuccess) {
						sucMsg = opts.onSuccess.call(target, data);
					}
					if (opts.dialog) {
						if ((!sucMsg) || (sucMsg == "")) {
							sucMsg = "成功";
						}
						successMessage(target, sucMsg);
					} else {
						opts.readonly = true;
						$.jsonloader(this, opts);
					}
				},
				error : function(xhr, status) {
					if (opts.dialog) {
						var btns = getButtons(target);
						$(btns[0]).linkbutton({
							text : opts.submit.name,
							iconCls : opts.submit.iconCls
						});
						$(btns[0]).linkbutton('enable');
					}
					var e = JSON.parse(xhr.responseText);
					alert(e.message);
				}
			});
		}
		return true;
	}

	function transformDate(target, data) {
		for (var i = 0; i < data.rows.length; i++) {
			var row = data.rows[i];
			var inputs = $(target).find(
					"td.joyform-editor input[name='" + row.name
							+ "'],td.joyform-editor textarea[name='" + row.name + "']");
			if (inputs) {
				var input = $(inputs[0]);
				if (input.attr('type') == 'checkbox') {
					if (input.attr('checked')) {
						row.value = true;
					} else {
						row.value = false;
					}
				} else {
					row.value = input.val();
				}
			}
		}
	}

	function validate(target) {
		if ($.fn.validatebox) {
			var t = $(target);
			t.find('.validatebox-text:not(:disabled)').validatebox('validate');
			var invalidbox = t.find('.validatebox-invalid');
			invalidbox.filter(':not(:disabled):first').focus();
			return invalidbox.length == 0;
		}
		return true;
	}

	function successMessage(target, msg) {
		var btns = getButtons(target);
		$(btns[0]).remove();
		var content = getContent(target);
		content.empty();
		var th = $("<tr><th><th></tr>").appendTo(content);
		$("<div></div>").appendTo(th).addClass("joyform-success").html(msg);
	}

	$.fn.joyform.methods = $.extend({}, $.fn.dialog.methods, {
		options : function(jq) {
			return $.data(jq[0], 'joyform').options;
		},
		getData : function(jq) {
			return $.data(jq[0], 'joyform').data;
		},
		load : function(jq, data) {
			return jq.each(function() {
				loadData(this, data);
			});
		},
		reload : function(jq, readonly) {
			return jq.each(function() {
				var opts = $.data(this, 'joyform').options;
				if (readonly) {
					opts.readonly = true;
				} else {
					opts.readonly = false;
				}
				$.jsonloader(this, opts);
			});
		}
	});

	$.fn.joyform.defaults = $.extend({}, $.jsonloader.defaults, {
		title : null,
		width : 400,
		height : 200,
		data : null,
		dialog : false,
		readonly : false,
		submit : {
			name : "确认",
			iconCls : "icon-ok",
			url : null,
		},
		onSubmit : function(data) {
		},
		onSuccess : function(param) {
			return "成功";
		}
	});

	var cssloaded = false;
	if (window.jQuery) {
		jQuery(function() {
			if (!cssloaded) {
				easyloader.load('extends/joyform.css', function() {
					cssloaded = true;
				});
			}
		});
	}
})(jQuery);